本当に動く!? IPv6 で GRE over IPsec を試す
こんにちは、VPN 芸人のトランです。みなさんいかがお過ごしでしょうか?
きょうは、トンネリングによるクラウド接続の可能性を探るべく GRE over IPsec を IPv6 トランスポートで行う方法についてご紹介したいと思います。
GRE over IPsec とは?
GRE over IPsec は、GRE のパケットを IPsec でカプセル化するための仕組みです。この際、IPsec SA は一般的なトンネルモードではなくトランスポートモードで確立され、ESP によるカプセル化の際に GRE パケットの IP ヘッダは削除されます。これは、IPsec におけるトランスポートモードがトンネルモードと対照的に Host-to-Host の VPN 接続で使用することを想定しており、トランスポートモードで GRE パケットの IP ヘッダを省略することによってオーバーヘッドの削減、カプセル化に必要な計算リソースの低減を実現しているためです。
なお、一般的に GRE over IPsec はルーター同士で安全なチャネル (IPsec) を確立しつつ IPsec のトンネルモード (Layer 3 VPN) では使用できない IGP (EIGRP、OSPF、IS-IS、RIPv2 など) を使用するための仕組みとされます。
今回は、Linux の世界で用いられることがごく稀であるとされる GRE over IPsec を AWS 側では Debian + strongSwan の組み合わせで終端する一方、オンプレミスでは IOS ルーターで終端、かつトランスポートとして IPv6 を使用するアーキテクチャが有効であるか検証してみたいと思います。
なぜ Debian と strongSwan なのか
Amazon Linux 2 では Libreswan と呼ばれる IPsec 実装がサポートされますが、残念ながら Libreswan では IOS ルーターとの IPsec over IPv6 が期待通りに動作しません。strongSwan (スイス生まれ!) は Debian 系のディストリビューションで多用される IPsec 実装ですが、Libreswan より活発にメンテナンスが行われており、様々なシチュエーション (Host-to-HostかSite-to-Siteか、IKEv1かIKEv2か、IPv4かIPv6か...) で実際にテストされた設定例が公開されているのが利点です。Amazon Linux 2 でサポートされる IPsec 実装でないのが残念ですが、Debian の AMI は AWS Marketplace で提供される一方で ENA への対応もいち早く行われていることから今回は strongSwan を使って検証していきたいと思います。
検証
まず、通常の GRE トンネルを over IPv6 で作成します。Debian では以下の要領で行いましょう。なお、実は一番難しかったステップがここです (Linux における GRE over IPv6 構成例の少なさ!)
# ip -f inet6 tunnel add ip6gre4 mode ip6gre remote 2001:1620:1111:2222:3333:4444:5555:6666 local 2a05:d014:9c9:2100:9049:489e:d66e:41e9 # ip -f inet6 tunnel show ip6gre4 ip6gre4: gre/ipv6 remote 2001:1620:1111:2222:3333:4444:5555:6666 local 2a05:d014:9c9:2100:9049:489e:d66e:41e9 encaplimit 4 hoplimit 64 tclass 0x00 flowlabel 0x00000 (flowinfo 0x00000000) # ip address add 169.254.123.1/30 dev ip6gre4 # ip address show dev ip6gre4 7: ip6gre4@NONE: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 8949 qdisc noqueue state UNKNOWN group default qlen 1 link/gre6 2a:05:d0:14:09:c9:21:00:90:49:48:9e:d6:6e:41:e9 peer 20:01:16:20:11:11:22:22:33:33:44:44:55:55:66:66 inet 169.254.123.1/30 scope global ip6gre4 valid_lft forever preferred_lft forever # ip link set ip6gre4 up # ip link show ip6gre4 7: ip6gre4@NONE: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 8949 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1 link/gre6 2a:05:d0:14:09:c9:21:00:90:49:48:9e:d6:6e:41:e9 peer 20:01:16:20:11:11:22:22:33:33:44:44:55:55:66:66
ip コマンドを使用して作成したトンネルインターフェイスは OS を再起動すると失われてしまうので、以下を /etc/network/interfaces に追加するのがおすすめです。ここが本当に難しかった... 探した中ではこのページが唯一、再起動を生き延びる GRE over IPv6 の設定例を示したページでした。
auto ip6gre4 iface ip6gre4 inet static address 169.254.123.1/30 pre-up ip -family inet6 tunnel add ip6gre4 mode ip6gre remote 2001:1620:1111:2222:3333:4444:5555:6666 local 2a05:d014:9c9:2100:9049:489e:d66e:41e9
オンプレミスの IOS ルーターでも、以下の要領で GRE over IPv6 のトンネルを作成します。
! interface Tunnel46 ip address 169.254.123.2 255.255.255.252 tunnel source 2001:1620:1111:2222:3333:4444:5555:6666 tunnel mode gre ipv6 tunnel destination 2A05:D014:9C9:2100:9049:489E:D66E:41E9 end !
Debian の GRE インターフェイスへ ICMP Echos を送ります。問題なく疎通できていますね!
ip-10-189-112-1(config)#do ping 169.254.123.1 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 169.254.123.1, timeout is 2 seconds: !!!!! Success rate is 100 percent (5/5), round-trip min/avg/max = 12/14/16 ms
GRE トンネルが用意できたので、GRE パケットを IPsec (ESP) でカプセル化すべく必要な設定を行います。ステップは以下の通りです。
- IPsec の Phase 1 SA に必要な Proposal を作成します。
- IPsec の Phase 1 SA に必要な Profile を作成します。
- IPsec の Phase 2 SA に必要な Transform-Set を作成します。
- Crypto Map で使用する Access-List を作成します。
- 物理インターフェイスに適用するための Crypto Map を作成します。
- 物理インターフェイスに Crypto Map を適用します。
まず、1から3を以下の要領で行います。既に IPsec 関連の設定が存在する場合、コンフリクトしないように注意しましょう。
! crypto ikev2 proposal 10 encryption aes-cbc-128 integrity sha1 group 2 exit ! crypto ikev2 profile 10 match address local 2001:1620:1111:2222:3333:4444:5555:6666 match identity remote address 2A05:D014:9C9:2100:97B7:D1BB:CF83:7B6D/128 identity local address 2001:1620:1111:2222:3333:4444:5555:6666 authentication remote pre-share key MyFavouriteMealIsRaclette authentication local pre-share key MyFavouriteMealIsRaclette lifetime 28800 exit ! crypto ipsec transform-set 10 esp-aes esp-sha-hmac mode tunnel exit !
次に、物理インターフェイス (今回は Dialer0) から Debian インスタンスへ向かう GRE パケットを ESP でカプセル化するような Crypto Map を用意します。
! ipv6 access-list gre-over-ipsec-10 permit 47 host 2001:1620:1111:2222:3333:4444:5555:6666 host 2A05:D014:9C9:2100:97B7:D1BB:CF83:7B6D exit ! crypto map ipv6 gre-over-ipsec-10 local-address Dialer0 ! crypto map ipv6 gre-over-ipsec-10 10 ipsec-isakmp set peer 2A05:D014:9C9:2100:97B7:D1BB:CF83:7B6D set transform-set 10 set pfs group2 set ikev2-profile 10 match address gre-over-ipsec-10 exit ! interface Dialer0 ipv6 crypto map gre-over-ipsec-10 exit !
Debian インスタンスで strongSwan をインストールします。
# apt-get update # apt-get install charon-systemd # systemctl status strongswan-swanctl ● strongswan-swanctl.service - strongSwan IPsec IKEv1/IKEv2 daemon using swanctl Loaded: loaded (/lib/systemd/system/strongswan-swanctl.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2019-02-15 13:39:37 UTC; 15s ago Process: 8954 ExecStartPost=/usr/sbin/swanctl --load-all --noprompt (code=exited, status=0/SUCCESS) Main PID: 8934 (charon-systemd) Status: "charon-systemd running, strongSwan 5.5.1, Linux 4.9.0-8-amd64, x86_64" Tasks: 17 (limit: 4915) CGroup: /system.slice/strongswan-swanctl.service └─8934 /usr/sbin/charon-systemd
strongSwan のインストール時に作成された設定例をバックップします。
# mv /etc/swanctl/swanctl.conf /etc/swanctl/swanctl.conf.original
新しい設定ファイルを作成します。
# nano /etc/swanctl/swanctl.conf
connections { gw-gw { local_addrs = 2a05:d014:9c9:2100:9049:489e:d66e:41e9 remote_addrs = 2001:1620:1111:2222:3333:4444:5555:6666 local { auth = psk id = 2a05:d014:9c9:2100:9049:489e:d66e:41e9 } remote { auth = psk id = 2001:1620:1111:2222:3333:4444:5555:6666 } children { gre { local_ts = dynamic[gre] remote_ts = dynamic[gre] mode = transport updown = /usr/local/libexec/ipsec/_updown iptables esp_proposals = aes128-sha1-modp1024 } } version = 2 proposals = aes128-sha1-modp1024 } } secrets { ike-1 { id-1a = 2a05:d014:9c9:2100:9049:489e:d66e:41e9 id-1b = 2001:1620:1111:2222:3333:4444:5555:6666 secret = MyFavouriteMealIsRaclette } }
作成した設定ファイルを strongSwan に読み込みます。
# swanctl --load-all # swanctl --list-conns gre-over-ipv6: IKEv2, no reauthentication, rekeying every 14400s local: 2a05:d014:9c9:2100:9049:489e:d66e:41e9 remote: 2001:1620:1111:2222:3333:4444:5555:6666 local pre-shared key authentication: id: 2a05:d014:9c9:2100:9049:489e:d66e:41e9 remote pre-shared key authentication: id: 2001:1620:1111:2222:3333:4444:5555:6666 gre: TRANSPORT, rekeying every 3600s local: dynamic[gre] remote: dynamic[gre]
改めて ICMP Echos を送ってみます。きちんと通っていますね!
ip-10-189-112-1(config)#do ping 169.254.123.1 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 169.254.123.1, timeout is 2 seconds: .!!!! Success rate is 80 percent (4/5), round-trip min/avg/max = 12/14/16 ms
実際に GRE パケットが IPsec でカプセル化されていることを確認するには、show crypto ikev2 や show crypto ipsec が有効です。うっかり Crypto Map が外れて GRE パケットが平文でインターネットに流れることを心配する場合、セキュリティグループやアクセスリストで GRE パケットを拒否してしまうのが有効です。
ip-10-189-112-1(config)#do show crypto ikev2 session IPv4 Crypto IKEv2 Session IPv6 Crypto IKEv2 Session Session-id:4, Status:UP-ACTIVE, IKE count:1, CHILD count:1 Tunnel-id fvrf/ivrf Status 1 none/none READY Local 2001:1620:1111:2222:3333:4444:5555:6666/500 Remote 2A05:D014:9C9:2100:97B7:D1BB:CF83:7B6D/500 Encr: AES-CBC, keysize: 128, PRF: SHA1, Hash: SHA96, DH Grp:2, Auth sign: PSK, Auth verify: PSK Life/Active Time: 28800/390 sec Child sa: local selector 2001:1620:1111:2222:3333:4444:5555:6666/0 - 2001:1620:1111:2222:3333:4444:5555:6666/65535 remote selector 2A05:D014:9C9:2100:97B7:D1BB:CF83:7B6D/0 - 2A05:D014:9C9:2100:97B7:D1BB:CF83:7B6D/65535 ESP spi in/out: 0xE54FA0A2/0xCCA92CD0
せっかくなので、別のインスタンス (100.82.142.123) で起動した iperf3 と手元のホスト (10.189.10.6) で GRE over IPsec 経由のスループットを計ってみました!
$ ./iperf3 -f m -c 100.82.142.123 -P 4 -R Connecting to host 100.82.142.123, port 5201 Reverse mode, remote host 100.82.142.123 is sending [ 4] local 10.189.10.6 port 61728 connected to 100.82.142.123 port 5201 [ 6] local 10.189.10.6 port 61729 connected to 100.82.142.123 port 5201 [ 8] local 10.189.10.6 port 61730 connected to 100.82.142.123 port 5201 [ 10] local 10.189.10.6 port 61731 connected to 100.82.142.123 port 5201 [ ID] Interval Transfer Bandwidth [ 4] 0.00-1.00 sec 1.76 MBytes 14.7 Mbits/sec [ 6] 0.00-1.00 sec 950 KBytes 7.78 Mbits/sec [ 8] 0.00-1.00 sec 991 KBytes 8.12 Mbits/sec [ 10] 0.00-1.00 sec 1009 KBytes 8.27 Mbits/sec [SUM] 0.00-1.00 sec 4.64 MBytes 38.9 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ 4] 1.00-2.00 sec 1.32 MBytes 11.1 Mbits/sec [ 6] 1.00-2.00 sec 1.07 MBytes 8.98 Mbits/sec [ 8] 1.00-2.00 sec 732 KBytes 6.00 Mbits/sec [ 10] 1.00-2.00 sec 1.11 MBytes 9.34 Mbits/sec [SUM] 1.00-2.00 sec 4.22 MBytes 35.4 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ 4] 2.00-3.00 sec 1.43 MBytes 12.0 Mbits/sec [ 6] 2.00-3.00 sec 722 KBytes 5.92 Mbits/sec [ 8] 2.00-3.00 sec 671 KBytes 5.49 Mbits/sec [ 10] 2.00-3.00 sec 842 KBytes 6.90 Mbits/sec [SUM] 2.00-3.00 sec 3.61 MBytes 30.3 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ 4] 3.00-4.00 sec 1.21 MBytes 10.1 Mbits/sec [ 6] 3.00-4.00 sec 911 KBytes 7.47 Mbits/sec [ 8] 3.00-4.00 sec 1.21 MBytes 10.1 Mbits/sec [ 10] 3.00-4.00 sec 1.43 MBytes 12.0 Mbits/sec [SUM] 3.00-4.00 sec 4.74 MBytes 39.8 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ 4] 4.00-5.00 sec 1.20 MBytes 10.1 Mbits/sec [ 6] 4.00-5.00 sec 1.31 MBytes 11.0 Mbits/sec [ 8] 4.00-5.00 sec 1.51 MBytes 12.7 Mbits/sec [ 10] 4.00-5.00 sec 1.71 MBytes 14.4 Mbits/sec [SUM] 4.00-5.00 sec 5.73 MBytes 48.1 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ 4] 5.00-6.00 sec 1.24 MBytes 10.4 Mbits/sec [ 6] 5.00-6.00 sec 940 KBytes 7.70 Mbits/sec [ 8] 5.00-6.00 sec 1.54 MBytes 12.9 Mbits/sec [ 10] 5.00-6.00 sec 1.06 MBytes 8.89 Mbits/sec [SUM] 5.00-6.00 sec 4.76 MBytes 39.9 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ 4] 6.00-7.00 sec 1.08 MBytes 9.08 Mbits/sec [ 6] 6.00-7.00 sec 790 KBytes 6.47 Mbits/sec [ 8] 6.00-7.00 sec 1.44 MBytes 12.1 Mbits/sec [ 10] 6.00-7.00 sec 835 KBytes 6.84 Mbits/sec [SUM] 6.00-7.00 sec 4.11 MBytes 34.5 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ 4] 7.00-8.00 sec 748 KBytes 6.10 Mbits/sec [ 6] 7.00-8.00 sec 918 KBytes 7.49 Mbits/sec [ 8] 7.00-8.00 sec 1.31 MBytes 11.0 Mbits/sec [ 10] 7.00-8.00 sec 1.22 MBytes 10.2 Mbits/sec [SUM] 7.00-8.00 sec 4.16 MBytes 34.8 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ 4] 8.00-9.00 sec 1.06 MBytes 8.92 Mbits/sec [ 6] 8.00-9.00 sec 1.10 MBytes 9.23 Mbits/sec [ 8] 8.00-9.00 sec 1.38 MBytes 11.6 Mbits/sec [ 10] 8.00-9.00 sec 1.42 MBytes 11.9 Mbits/sec [SUM] 8.00-9.00 sec 4.95 MBytes 41.7 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ 4] 9.00-10.00 sec 1.28 MBytes 10.7 Mbits/sec [ 6] 9.00-10.00 sec 1.10 MBytes 9.20 Mbits/sec [ 8] 9.00-10.00 sec 1.18 MBytes 9.86 Mbits/sec [ 10] 9.00-10.00 sec 1.51 MBytes 12.7 Mbits/sec [SUM] 9.00-10.00 sec 5.06 MBytes 42.4 Mbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bandwidth Retr [ 4] 0.00-10.00 sec 12.5 MBytes 10.5 Mbits/sec 117 sender [ 4] 0.00-10.00 sec 12.5 MBytes 10.5 Mbits/sec receiver [ 6] 0.00-10.00 sec 9.84 MBytes 8.26 Mbits/sec 99 sender [ 6] 0.00-10.00 sec 9.84 MBytes 8.26 Mbits/sec receiver [ 8] 0.00-10.00 sec 12.1 MBytes 10.2 Mbits/sec 101 sender [ 8] 0.00-10.00 sec 12.1 MBytes 10.2 Mbits/sec receiver [ 10] 0.00-10.00 sec 12.2 MBytes 10.3 Mbits/sec 74 sender [ 10] 0.00-10.00 sec 12.2 MBytes 10.3 Mbits/sec receiver [SUM] 0.00-10.00 sec 46.7 MBytes 39.2 Mbits/sec 391 sender [SUM] 0.00-10.00 sec 46.7 MBytes 39.2 Mbits/sec receiver iperf Done.
すごく遅い...
結論
GRE over IPsec は Linux と IOS ルーター、IPv6 トランスポートの組み合わせでもきちんと動くことがわかりました。ただしエントリークラスのルーター (890 Series ISR) では 40 Mbps 程度のスループットしか出ないことがわかったので、IPsec は Linux VM などで終端することを考えたいと思います。
したっけまた!
謝辞
今回の検証にあたり、以下を参考にさせていただきました。この場を借りて心から御礼申し上げます。
IT Blogtorials: Decrypt IPsec packets - Linux to Cisco VPN http://ithitman.blogspot.com/2012/05/how-to-decrypt-ipsec-packets.html
Decrypting ESP payloads using Wireshark - Fortinet Cookbook
[hsmr] Hackspace Marburg · Freifunk/IC Peering Konfiguration https://hsmr.cc/Freifunk/ICPeeringKonfiguration
Route-based VPNs - strongSwan https://wiki.strongswan.org/projects/strongswan/wiki/RouteBasedVPN
Security for VPNs with IPsec Configuration Guide, Cisco IOS Release 15M&T - Cisco https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/sec_conn_vpnips/configuration/15-mt/sec-sec-for-vpns-w-ipsec-15-mt-book.html
Point-to-Point GRE over IPsec Design Guide - Preface [Design Zone for IPv6] - Cisco https://www.cisco.com/c/en/us/td/docs/solutions/Enterprise/WAN_and_MAN/P2P_GRE_IPSec/P2P_GRE/p2pGREPf.html
CCIE Routing & Switching v5.1 Advanced Technologies - INE https://streaming.ine.com/c/route-switch-atc